﻿using System;
using System.Collections.Generic;
using System.Text;
using com.lover.astd.common.model;

namespace com.lover.astd.common.manager 
{
    public class WeaponHelper
    {
        // 炮 | 钉 | 角 | 锋 | 灯 | 旗 | 车 
        private static int[] _redStandards = new int[7] { 300, 200, 500, 300, 180, 500, 100 };
        private static double[] _redFactors = new double[7] { 1, 1.5, 2, 2.5, 3, 4, 6 };
        private static double[] _purpleStandards = new double[7] { 2040, 1360, 3400, 2040, 1224, 3400, 680 };
        private static double[] _purpleInc_20 = new double[7] { 102, 68, 170, 102, 61.2, 170, 34 };
        private static double[] _purpleInc_30 = new double[7] { 126, 84, 210, 126, 75.6, 210, 42 };
        // 40星以下按照以上两个表来计算, 40星以上按照每10星中的星级数值差增加一个_purpleInc_40plus数值计算, 
        // 60星以上每星增加的数值恒定不变了
        // 比如: 40星角基础值是7200, 那么43星=7200+(210+70*1)*3=8040, 而53星=7200+(210+70*1)*10+(210+70*2)*3=11050
        private static double[] _purpleInc_40plus = new double[7] { 42, 28, 70, 42, 25.2, 70, 14 }; //42

        public static int getRedWeaponBaseAmount(Equipment equip)
        {
            if (equip.goodstype != GoodsType.Weapon) return 0;
            return _redStandards[(int)equip.Type - 1];
        }
        public static int getRedWeaponMaxAmount(Equipment equip)
        {
            if (equip.goodstype != GoodsType.Weapon) return 0;
            return (int)(_redStandards[(int)equip.Type - 1] * _redFactors[6]);
        }
        public static int getPurpleWeaponBaseAmount(int type, int star)
        {
            if (type < 0 || type > 7 || star < 20) return 0;

            double baseStandard = _purpleStandards[type];
            int inc_20 = star > 30 ? 10 : star - 20;
            int inc_30 = star > 40 ? 10 : star - 30;
            if (inc_20 < 0) inc_20 = 0;
            if (inc_30 < 0) inc_30 = 0;

            double standard_double = baseStandard + _purpleInc_20[type] * inc_20 + _purpleInc_30[type] * inc_30;

            if (star > 40)
            {
                int tmpstar = 40, inctimes = 1;
                while (tmpstar < star)
                {
                    int interval = star - tmpstar;
                    int inc = interval > 10 ? 10 : interval;
                    if(tmpstar < 60)
                        standard_double += (_purpleInc_30[type] + _purpleInc_40plus[type] * inctimes) * inc;
                    else
                        standard_double += (_purpleInc_30[type] + _purpleInc_40plus[type] * 3) * inc;
                    tmpstar += 10;
                    inctimes++;
                }
            }
            int standard = (int)standard_double;
            return standard;
        }
        public static int calcRedWeaponStar(Equipment equip)
        {
            if (equip.goodstype != GoodsType.Weapon) return 0;
            int eqtype = (int)equip.Type - 1;
            int weaponStandard = _redStandards[eqtype];
            int weaponMax = (int)(weaponStandard * _redFactors[6]);
            int weaponAmount = equip.ValueNow;
            // calculate star
            int star = 0;
            for (int i = 0; i < 7; i++)
            {
                if ((int)(weaponStandard * _redFactors[i]) > weaponAmount)
                {
                    star = i - 1;
                    break;
                }
            }
            return star;
        }
        public static double getPurpleWeaponFullToughness(int star)
        {
            // 根据网上流传的坚韧度计算器, 45级为37.6%, 45级以下安装每级增加1.1%来算, 120级以上安装每级增加4.4%来算
            double[] toughness_array = new double[] {
                37.60, //45级
                38.70,  39.80,  40.90,  42.00,  43.10,  44.25,  45.40,  46.55,  47.70,  48.85,  50.00,  51.20,  52.40,  53.60,  54.80,  //46-60
                56.10,  57.40,  58.70,  60.00,  61.30,  62.70,  64.10,  65.50,  66.90,  68.30,  69.90,  71.50,  73.10,  74.70,  76.30,  //61-75
                78.10,  79.90,  81.70,  83.50,  85.30,  87.40,  89.50,  91.60,  93.80,  95.90,  98.10,  100.30, 102.50, 104.70, 107.00, //76-90
                109.30, 111.60, 113.90, 116.20, 118.50, 120.80, 123.10, 125.40, 127.70, 130.00, 132.30, 134.60, 136.90, 139.10, 141.40, //91-105
                143.70, 146.00, 148.30, 150.70, 153.80, 156.90, 160.00, 163.10, 166.80, 170.50, 174.90, 179.30, 183.70, 188.10, 192.50  //106-120
            };
            double result = 0;
            if (star < 45) result = toughness_array[0] - (45 - star) * 0.6;
            else if (star >= 45 && star <= 120) result = toughness_array[star - 45];
            else result = toughness_array[toughness_array.Length - 1] + (star - 120) * 4.4;
            return result * 0.01;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="toughness">装备</param>
        /// <param name="toughness">如果是紫兵器, 那么期望的星级</param>
        /// <param name="toughness">输出参数, 如果是紫兵器, 那么期望的星级数值</param>
        /// <param name="toughness">输出参数, 坚韧度, 小数</param>
        /// <param name="full_toughness">输出参数, 满坚韧度, 小数</param>
        /// <param name="failcount">输出参数, 失败次数</param>
        /// <param name="needcount">输出参数, 如果是红兵器, 则是还需多少次一次升级</param>
        public static void getWeaponInfo(Equipment equip, int star_expect, out int amount_expect,
            out double toughness, out double full_toughness, out int failcount, out int needcount)
        {
            toughness = 0; full_toughness = 0; failcount = 0; needcount = 0; amount_expect = 0;
            if (equip.goodstype != GoodsType.Weapon) return;
            int eqtype = (int)equip.Type - 1;
            if (equip.Quality == EquipmentQuality.Red) //如果是红兵器
            {
                int weaponStandard = _redStandards[eqtype];
                int weaponMax = (int)(weaponStandard * _redFactors[6]);
                int weaponAmount = equip.ValueNow;
                // calculate star
                int star = calcRedWeaponStar(equip);
                // calculate strong
                int baseAmount = (int)(weaponStandard * _redFactors[star]);
                toughness = (weaponAmount - baseAmount) * 1.0 / baseAmount;
                amount_expect = (int)(weaponStandard * _redFactors[star + 1] * (1 + toughness));
                failcount = (int)(toughness * 255 / 0.24);
                needcount = (int)Math.Pow(2, star + 3) - 1 - failcount;
            }
            else if (equip.Quality == EquipmentQuality.Purple) //如果是紫兵器
            {
                int amount = equip.ValueNow;
                int star = equip.Level;
                int standard = getPurpleWeaponBaseAmount(eqtype, star);
                toughness = (amount - standard) * 1.0 / standard;
                full_toughness = getPurpleWeaponFullToughness(star);
                int standard_expect = getPurpleWeaponBaseAmount(eqtype, star_expect);
                amount_expect = (int)(standard_expect * (1 + toughness));
                failcount = (int)(toughness * 100 / 0.02);
            }
        }
    }
}
